import OpenPage from '@/components/OpenPage'
import { checkPermission } from '@/apis/index'
import { getAtlasState } from '@/apis/atlas'
import { Dialog, Toast } from 'vant'
import store from '@/store'
export const toString = Object.prototype.toString

export function Type(v) {
  return toString.call(v).replace(/\[object (.*)\]/, '$1')
}

export function isType(v, typeStr) {
  return Type(v).toLowerCase() === typeStr.toLowerCase()
}

export function isUndef(v) {
  return v === undefined || v === null
}

export function isDef(v) {
  return v !== undefined && v !== null
}

export function isEmpty(v) {
  return v === ''
}

export function deepCopy(v) {
  if (typeof v !== 'object') {
    return v
  }
  let copyV
  if (isType(v, 'Array')) {
    copyV = []
    for (let e of v) {
      e = deepCopy(e)
      copyV.push(e)
    }
  } else if (isType(v, 'Object')) {
    copyV = {}
    // eslint-disable-next-line prefer-const
    for (let [k, _v] of Object.entries(v)) {
      _v = deepCopy(_v)
      copyV[k] = _v
    }
  }
  return copyV
}
//
export function randomId() {
  return (Math.random() * 0xfffffff).toFixed().toString(16)
}
const opt = { passive: true }
export function touch(cb, ctx, ...args) {
  let clientX, clientY, timerid
  const touchstart = e => {
    const touche = e.touches[0]
    clientX = touche.clientX
    clientY = touche.clientY
  }
  window.addEventListener('touchstart', touchstart, opt)
  const touchmove = e => {
    const touche = e.changedTouches[0]
    // let x, y
    // window.pageXOffset > 0 ? x = touche.clientX - clientX : ''
    // window.pageYOffset > 0 ? y = touche.clientY - clientY : ''
    if (timerid)clearTimeout(timerid)
    timerid = setTimeout(() => {
      cb.apply(ctx, [...args, touche.clientX - clientX, touche.clientY - clientY])
      timerid = null
    }, 50)
  }
  window.addEventListener('touchmove', touchmove, opt)
  return () => {
    window.removeEventListener('touchstart', touchstart, opt)
    window.removeEventListener('touchmove', touchmove, opt)
  }
}
// 提取筛选结果
export function extrFilterData(list, deep = true) {
  if (deep) {
    list = deepCopy(list)
  }
  return list.filter(e => {
    if (e.unId) {
      e.children = extrFilterData(e.children || [], false)
    }
    return (e.selected || (e.unId && e.children.some(e => e.selected)))
  })
}
// 提取指定筛选结果
export function extrFIlterByFlag(list, flag, deep = true) {
  if (deep) {
    list = deepCopy(list)
  }
  const result = []
  for (const item of list) {
    if (!item.unId) {
      continue
    }
    const eqFlag = flag instanceof RegExp ? flag.test(item.flag) : item.flag === flag
    if (eqFlag && item.children && item.children.length > 0) {
      result.push(item)
    } else if (item.children) {
      result.push(...extrFIlterByFlag(item.children, flag, false))
    }
  }
  for (const r of result) {
    if (!r.children) {
      r.children = []
    }
  }
  return result
}
// 提取指定筛选结果值
export function extrFIlterValue(data, join = true, sep = ',', filedName = 'value') {
  const result = []
  for (const d of data) {
    for (const c of d.children) {
      result.push(c[filedName])
    }
  }
  return join ? result.join(sep) : result
}
export function extrFIlterValueByFlag(list, flag, join = true, sep = ',') {
  return extrFIlterValue(extrFIlterByFlag(list, flag), join, sep, 'value')
}
export function extrFIlterIdxByFlag(list, flag, join = true, sep = ',') {
  return extrFIlterValue(extrFIlterByFlag(list, flag), join, sep, 'idx')
}
// 获取属性ev格式
export function extrEvsValueByFlag(data, join = true, sep = ',') {
  const result = []
  for (const d of data) {
    for (const c of d.children) {
      result.push(`${d.value}_${c.value}`)
    }
  }
  return join ? result.join(sep) : result
}
export function extrFIlterEvsValueByFlag(list, flag, join = true, sep = ',') {
  return extrEvsValueByFlag(extrFIlterByFlag(list, flag), join, sep)
}

// 合并filterData数据, 商品中心使用
export function concatFilterData(list, raw) {
  for (const item of list) {
    concatItem(item, raw)
    if (item.children && item.children.length > 0) {
      concatFilterData(item.children, raw)
    }
  }
}
// 合并item
export function concatItem(item, raw) {
  for (const r of raw) {
    if (item.flag && r.flag && item.flag === r.flag && r.unId && item.unId) {
      item.unId = r.unId
    }
    item.fold = r.fold
    if (item.id === r.id && item.name === r.name) {
      // 处理关联信息
      item.relevanceItemShow = r.relevanceItemShow
      // console.log(item.name,r.name)
      item.selected = r.selected
      return
    } else if (r.children && r.children.length > 0) {
      concatItem(item, r.children)
    }
  }
}
// 打开新页面
export function openPage(url, target = '_blank') {
  // Dialog.confirm({
  //   title: '打开外部链接',
  //   message: url
  // }).then(() => {
  //   !/^(https?:\/\/)+/.test(url) ? url = `https://${url}` : ''
  //   window.open(url, target)
  // })
  // const a = document.createElement('a')
  // a.href = url
  // a.target = target
  // a.click()
  OpenPage(url, target)
}

export function findItem(item, ...args) {
  for (const arg of args) {
    let hasItem = false
    for (const i of arg) {
      if (i === item) {
        hasItem = true
        break
      }
    }
    if (!hasItem) {
      return false
    }
  }
  return true
}
// 取交集
export function unite(...args) {
  if (args.length === 0) return args
  if (args.length === 1) return args[0]
  const uniteData = []
  for (let i = 0; i < args.length; i++) {
    const arg = args[i]
    const newArgs = [...args.slice(0, i), ...args.slice(i + 1)]
    for (const item of arg) {
      if (findItem(item, ...newArgs)) {
        uniteData.push(item)
      }
    }
  }
  return Array.from(new Set(uniteData))
}

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  if (!time) return ''
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string')) {
      if (time.indexOf('T')) {
        time = time.replace('T', ' ')
      }
      if (time.indexOf('Z')) {
        time = time.replace('Z', ' ')
      }
      if (/^[0-9]+$/.test(time)) {
        time = parseInt(time)
      } else {
        time = time.replace(/-/g, '/') // 处理safari与ie兼容
      }
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

// url路径格式化
export function formatURL(url, prefix) {
  if (!url || typeof url !== 'string') return ''
  if (!prefix) return url
  const Expression = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/
  const objExp = new RegExp(Expression)
  if (objExp.test(url)) {
    return url
  }
  if (url.indexOf('/') !== 0) {
    if (prefix.split('').pop() !== '/') {
      prefix = `${prefix}/`
    }
  } else {
    if (prefix.substr(-1) === '/') {
      prefix = prefix.substr(0, prefix.length - 1)
    }
  }

  return `${prefix}${url}`
}
/**
 * JSON对象转formData
 * @param {Object} JSON对象
  */
export function json2FormData(params) {
  const formData = new FormData()
  Object.keys(params).forEach((key) => {
    formData.append(key, params[key])
  })
  return formData
}

// 获取keepAlive实例，清除cache的同时，destory掉当前实例（在需要清除的时候调用）
export const removeKeepAliveCacheForVueInstance = (vueInstance) => {
  const key =
    vueInstance.$vnode.key ??
    vueInstance.$vnode.componentOptions.Ctor.cid + (vueInstance.$vnode.componentOptions.tag ? `::${vueInstance.$vnode.componentOptions.tag}` : '')
  const cache = vueInstance.$vnode.parent.componentInstance.cache
  const keys = vueInstance.$vnode.parent.componentInstance.keys
  if (cache[key]) {
    vueInstance.$destroy()
    delete cache[key]
    const index = keys.indexOf(key)
    if (index > -1) {
      keys.splice(index, 1)
    }
  }
}
// 移除所有缓存路由实例
export const removeAllRouterCache = (app) => {
  if (app.$children) {
    app.$children.filter(v => !!v.$vnode.key).forEach((vueInstance) => {
      const key = vueInstance.$vnode.key
      const cache = vueInstance.$vnode.parent.componentInstance.cache
      const keys = vueInstance.$vnode.parent.componentInstance.keys
      if (cache[key]) {
        vueInstance.$destroy()
        delete cache[key]
        const index = keys.indexOf(key)
        if (index > -1) {
          keys.splice(index, 1)
        }
      }
    })
  }
}
/**
 * @param {Object} data
 * @param {} router  路由对象
 * @param {Boolean} checkAuth 是否检查权限
*/
export const gotoPage = async(data, router, checkAuth = false) => {
  if (checkAuth) {
    const auth = await checkPermission(data.id)
    if (!auth) {
      Toast('资料筹备中，暂无查看权限，敬请期待！')
      return
    }
  }

  const { gotoType, gotoValue, filterId, categoryDTOList, subGotoType } = data
  const arrVal = gotoValue ? gotoValue.split('|') : []
  let categoryIds = []
  if (categoryDTOList && categoryDTOList.length > 0) {
    categoryIds = categoryDTOList.map(e => e.categoryId)
  }

  switch (gotoType) {
    case 'GOODS_CENTER_CATEGORY' :
      // 商品类目中心
      router.push({ path: '/product', query: { value: filterId, categoryIds: categoryIds.join('_'), title: data.routerTitle }})
      break
    case 'OUTSIDE_LINK' :
      // 外部链接
      router.push({ name: 'Outsite', query: { src: gotoValue, back: 1 }})
      break
    case 'APPLY_PAGE' :
      // 应用页面
      router.push({ path: gotoValue })
      break
    case 'ATLAS' :
      // 图册
      toATLASPage({ gotoName: data.gotoName, gotoValue }, router)
      break
    case 'HELP_CENTER' :
      // 帮助中心
      router.push({ path: '/helpCenter' })
      break
    case 'HELP_CENTER_DETAIL' :
      // 帮助中心详情
      router.push({ name: 'HelpCenterDetail', params: { id: gotoValue }, query: { hide: 1 }})
      break
    case 'CUSTOM_PAGE' :
      // 自定义页面
      router.push({ name: 'CustomPage', params: { id: gotoValue }})
      break
    case 'GOODS_CENTER_DETAIL' :
      // 商品详情
      if (arrVal.length !== 2) {
        break
      }
      router.push({ name: 'FinishedDetail', params: { spuId: arrVal[0], skuId: arrVal[1] }})
      break
    case 'GOODS_CATE' :
      // 商品分类
      router.push({ name: 'GoodsCategory' })
      break
    case 'CUSTOMIZED_NEW_PRODUCT_SERIES' :
      // 定制新品系列
      router.push({ name: 'CustomizedNewProductSeries', params: { id: gotoValue }})
      break
    case 'DEFINE_TAB' :
      // 自定义导航
      if (Number(subGotoType || 0) === 1) {
        // 导航
        router.push({ name: 'DefineTabNavigation', params: { id: gotoValue }, query: { title: data.gotoName || data.routerTitle }})
      } else if (Number(subGotoType || 0) === 2) {
        // 分类
        router.push({ name: 'DefineTabCategory', params: { id: gotoValue }, query: { title: data.gotoName || data.routerTitle }})
      } else if (Number(subGotoType || 0) === 3) {
        // 目录
        router.push({ name: 'DefineTabDirectory', params: { id: gotoValue }, query: { title: data.gotoName || data.routerTitle }})
      }
      break
    default:
      break
  }
}
export async function toATLASPage({ gotoName, gotoValue }, router) {
  let path = '/atlas'
  if ([null, undefined, ''].includes(gotoValue)) {
    router.push({ path })
    return
  }
  const ids = gotoValue.split('|')
  const names = gotoName.split('/')
  let atlasId = ''
  let atlasName = ''
  if (ids.length === 1) {
    // 一级图册
    atlasId = ids[0]
    atlasName = names[0] || ''
    path = `/atlas?confId=${atlasId}&atlasName=${atlasName}`
  } else if (ids.length === 2) {
    // 二级图册
    atlasId = ids[1]
    atlasName = names[1] || ''
    path = `/photo/atlas/child/${atlasId}?atlasName=${atlasName}&levelType=SECOND`
  } else if (ids.length === 3) {
    // 三级图册
    atlasId = ids[2]
    atlasName = names[2] || ''
    path = `/photo/atlas/last/preview/${atlasId}?atlasName=${atlasName}`
  }
  /*
  TODO:20230920 关闭图册校验（关联图册时，取消图册不可见提示，可正常访问不可见图册)
  const state = atlasId ? await getAtlasState(atlasId) : true
  if (state) {
    router.push({ path })
  } else {
    Dialog.confirm({
      // title: '提示',
      message: `图册【${atlasName}】不可见，是否前往查看其他图册？`,
      cancelButtonText: '关闭',
      confirmButtonText: '查看'
    }).then(() => {
      router.push({ path: '/atlas' })
    }).catch(() => {
    })
  } */
  router.push({ path })
}

export default {
  install(Vue) {
    Object.defineProperty(Vue.prototype, '$Type', { value: Type })
    Object.defineProperty(Vue.prototype, '$isType', { value: isType })
    Object.defineProperty(Vue.prototype, '$isUndef', { value: isUndef })
    Object.defineProperty(Vue.prototype, '$isDef', { value: isDef })
    Object.defineProperty(Vue.prototype, '$isEmpty', { value: isEmpty })
    Object.defineProperty(Vue.prototype, '$deepCopy', { value: deepCopy })
    Object.defineProperty(Vue.prototype, '$extrFilterData', { value: extrFilterData })
    Object.defineProperty(Vue.prototype, '$extrFIlterByFlag', { value: extrFIlterByFlag })
    Object.defineProperty(Vue.prototype, '$extrFIlterValue', { value: extrFIlterValue })
    Object.defineProperty(Vue.prototype, '$extrFIlterValueByFlag', { value: extrFIlterValueByFlag })
    Object.defineProperty(Vue.prototype, '$extrFIlterIdxByFlag', { value: extrFIlterIdxByFlag })
    Object.defineProperty(Vue.prototype, '$concatFilterData', { value: concatFilterData })
    Object.defineProperty(Vue.prototype, '$extrFIlterEvsValueByFlag', { value: extrFIlterEvsValueByFlag })
    Object.defineProperty(Vue.prototype, '$touch', { value: touch })
    Object.defineProperty(Vue.prototype, '$openPage', { value: openPage })
    Object.defineProperty(Vue.prototype, '$formatURL', { value: formatURL })
    Object.defineProperty(Vue.prototype, '$removeKeepAliveCache', { value: removeKeepAliveCacheForVueInstance })
    Object.defineProperty(Vue.prototype, '$removeAllRouterCache', { value: removeAllRouterCache })
    Object.defineProperty(Vue.prototype, '$gotoPage', { value: gotoPage })
  }
}

